﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Core.Helper;
using Core.Model;
using Channel = Core.Model.Channel;

namespace DataServer.View
{
    /// <summary>
    /// DeviceView.xaml 的交互逻辑
    /// </summary>
    public partial class DeviceView
    {
       // private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private readonly ObservableCollection<Channel> _channels = new ObservableCollection<Channel>();
        private readonly ObservableCollection<Device> _devices = new ObservableCollection<Device>();
        private Channel selectChannel;
        private Device selectDevice;
        private int _lastIndex = 1;
        public DeviceView()
        {
            InitializeComponent();
           
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }
            this.Loaded += DeviceView_Loaded;
            this.devicePanel.UpdateDataItems += DevicePanel_UpdateDataItems;
        }

        private void DevicePanel_UpdateDataItems(Device dev, List<DataItem> dataItems)
        {
            if(dev!=null && dataItems!=null && dataItems.Count > 0)
            {
                dataItemPanel.UpdateDataItems(selectDevice,dataItems);
            }
        }

        private void DeviceView_Loaded(object sender, RoutedEventArgs e)
        {
            if (AppManager.IsRunning)
            {
                this.IsEnabled = false;
                return;
            }
            this.IsEnabled = true;
            _channels.Clear();
            List<Channel> channels =AppManager.ChannelDao.GetEntities();
            if (channels != null)
            {
                foreach (Channel ch in channels)
                {
                    _channels.Add(ch);
                }
            }
            channelListBox.DataContext = _channels;
            if (_channels.Count > 0)
            {
                channelListBox.SelectedItem = _channels[0];
            }
        }
        private void ChannelListBox_OnMouseUp(object sender, MouseButtonEventArgs e)
        {
            selectDevice = null;
            var temp = channelListBox.SelectedItem as Channel;
            if (temp == selectChannel)
            {
                channelPanel.DataContext = null;
                channelPanel.DataContext = selectChannel;
            }
            if (tabCtrl.SelectedIndex != 0)
            {
                _lastIndex = tabCtrl.SelectedIndex > 0 ? tabCtrl.SelectedIndex : 1;
                tabCtrl.SelectedIndex = 0;
            }
        }
        private void ChannelListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            selectDevice = null;
            selectChannel = channelListBox.SelectedItem as Channel;
            channelPanel.DataContext = null;
            channelPanel.DataContext = selectChannel;
            _devices.Clear();
            if (selectChannel != null)
            {
                List<Device> devices = AppManager.DeviceDao.GetDevicesByChlId(selectChannel.Id);
                if (devices != null)
                {
                    foreach (Device dev in devices)
                    {
                        dev.DeviceType = AppManager.DeviceTypeDao.GetEntityById(dev.DeviceTypeId);
                        _devices.Add(dev);
                    }
                }
                deviceListBox.DataContext = _devices;
            }
            if (tabCtrl.SelectedIndex != 0)
            {
                _lastIndex = tabCtrl.SelectedIndex > 0 ? tabCtrl.SelectedIndex : 1;
                tabCtrl.SelectedIndex = 0;
            }
        }
        private void DeviceListBox_OnMouseUp(object sender, MouseButtonEventArgs e)
        {
            var device = deviceListBox.SelectedItem as Device;
            if (selectDevice != device)
            {
                selectDevice = device;
                devicePanel.DataContext = null;
                devicePanel.DataContext = selectDevice;
                tabCtrl.SelectedIndex = _lastIndex;
                if (selectDevice != null && tabCtrl.SelectedIndex == 2)
                {
                    try
                    {
                        selectChannel = _channels.First(sss => sss.Id == selectDevice.ChannelId);
                        dataItemPanel.UpdateDataItems(selectDevice);
                    }
                    catch
                    {
                    }
                }
            }
        }
        private void DeviceListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(new Action((() =>
            {
                var device = deviceListBox.SelectedItem as Device;
                if (selectDevice != device)
                {
                    selectDevice = device;
                    devicePanel.DataContext = null;
                    devicePanel.DataContext = selectDevice;
                    tabCtrl.SelectedIndex = _lastIndex;
                    if (selectDevice != null && tabCtrl.SelectedIndex == 2)
                    {
                        try
                        {
                            selectChannel = _channels.First(sss => sss.Id == selectDevice.ChannelId);
                            dataItemPanel.UpdateDataItems(selectDevice);
                        }
                        catch
                        {
                        }
                    }
                }
            })), DispatcherPriority.ApplicationIdle);
        }

        private void BtnAddChannel_OnClick(object sender, RoutedEventArgs e)
        {
            Channel newChannel=new Channel();
            newChannel.ChannelType = "SerialPortChannel";
            newChannel.Name = "新通道";
            newChannel.PollingDelay = 10;
            newChannel.Ip = "192.168.1.150";
            newChannel.Port = 4800;
            newChannel.Comport = "COM1";
            newChannel.DataBits = 8;
            newChannel.Baudrate = 9600;
            newChannel.Parity = Parity.None.ToString();
            newChannel.StopBits = StopBits.One.ToString();
            newChannel.ReadTimeout = 25;
            newChannel.WriteTimeout = 25;
            _channels.Add(newChannel);
            channelListBox.SelectedItem = _channels[_channels.Count - 1];
            AppManager.AddMemChannel(selectChannel); // 内存通道对象
            SaveChannels();
        }

        private void BtnDelChannel_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectChannel == null)
            {
                MessageBox.Show("请先选择通道!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            if(MessageBox.Show($"是否要删除通道<{selectChannel.Name}>及其关联的所有设备?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question)!= MessageBoxResult.Yes) return;
            AppManager.ChannelDao.DeleteEntity(selectChannel);
            List<Device> devices = AppManager.DeviceDao.GetDevicesByChlId(selectChannel.Id);
            if (devices != null && devices.Count > 0)
            {
                AppManager.DeviceDao.DeleteDevicesByChlId(selectChannel.Id);
                foreach (var device in devices)
                {
                    AppManager.DataItemDao.DeleteDataItemsByDeviceId(device.Id);
                }
            }
            _channels.Remove(selectChannel);
            AppManager.DelMemChannel(selectChannel); // 内存通道对象
            if (_channels.Count>0)
                channelListBox.SelectedItem = _channels[_channels.Count - 1];
        }
        private void BtnSaveChannel_OnClick(object sender, RoutedEventArgs e)
        {
            AppManager.ChannelDao.DeleteAllEntities();
            if (_channels.Count > 0)
            {
                for (int i = 0; i < _channels.Count; i++)
                {
                    _channels[i].Position = i;
                }
                if (AppManager.ChannelDao.InsertEntities(_channels.ToList()))
                {
                    MessageBox.Show("保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                else
                {
                    MessageBox.Show("保存失败!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
            channelListBox.DataContext = null;
            channelListBox.DataContext = _channels;
            if (_channels.Count > 0)
            {
                channelListBox.SelectedItem = _channels[0];
            }
        }
        private void BtnAddDevice_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectChannel == null)
            {
                MessageBox.Show("请先选择通道!","提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            Device device= new Device() { ChannelId = selectChannel.Id };
            device.Protocol = "ModbusRTUProtocol";
           
            _devices.Add(device);
            deviceListBox.SelectedItem = _devices[_devices.Count - 1];
            SaveDevices();
        }

        private void BtnDelDevice_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectDevice == null)
            {
                MessageBox.Show("请先选择设备!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            if (MessageBox.Show($"是否要删除设备<{selectDevice.Name}>及其关联的所有数据项?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return;

            AppManager.DeviceDao.DeleteEntity(selectDevice);
            AppManager.DataItemDao.DeleteDataItemsByDeviceId(selectDevice.Id);
            _devices.Remove(selectDevice);
            if(_devices.Count>0)
                deviceListBox.SelectedItem = _devices[_devices.Count - 1];
        }
        private void BtnSaveDevice_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectChannel != null)
                AppManager.DeviceDao.DeleteDevicesByChlId(selectChannel.Id);
            if (_devices.Count > 0)
            {
                for (int i = 0; i < _devices.Count; i++)
                {
                    _devices[i].Position = i;
                }
                if (AppManager.DeviceDao.InsertEntities(_devices.ToList()))
                {
                    MessageBox.Show("保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                else
                {
                    MessageBox.Show("保存失败!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
            deviceListBox.DataContext = null;
            deviceListBox.DataContext = _devices;
            if (_devices.Count > 0)
                deviceListBox.SelectedItem = _devices[_devices.Count - 1];

        }

        private void TabCtrl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (tabCtrl.SelectedIndex == 2 && _lastIndex != 2 && dataItemPanel.Device != selectDevice)
            {
                dataItemPanel.UpdateDataItems(selectDevice);
            }
            if (tabCtrl.SelectedIndex > 0)
            {
                _lastIndex = tabCtrl.SelectedIndex;
            }
        }

        private void SaveChannels()
        {
            AppManager.ChannelDao.DeleteAllEntities();
            if (_channels.Count > 0)
            {
                for (int i = 0; i < _channels.Count; i++)
                {
                    _channels[i].Position = i;
                }
                AppManager.ChannelDao.InsertEntities(_channels.ToList());
            }
        }

        private void SaveDevices()
        {
            if (selectChannel != null)
                AppManager.DeviceDao.DeleteDevicesByChlId(selectChannel.Id);
            if (_devices.Count > 0)
            {
                for (int i = 0; i < _devices.Count; i++)
                {
                    _devices[i].Position = i;
                }
                AppManager.DeviceDao.InsertEntities(_devices.ToList());
            }
        }


        private void MiChlCopy_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectChannel == null)
            {
                MessageBox.Show("请选择要复制的通道!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            Channel newChannel = selectChannel.Clone(IdHelper.GuidToString(), selectChannel.Name + "-复制");
            _channels.Add(newChannel);
            channelListBox.SelectedItem = _channels[_channels.Count - 1];
            AppManager.AddMemChannel(newChannel); // 内存通道对象
            SaveChannels();
        }
        private void MiChlCopyAll_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectChannel == null)
            {
                MessageBox.Show("请选择要复制的通道!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            string oldId = selectChannel.Id;
            Channel newChannel = selectChannel.Clone(IdHelper.GuidToString(), selectChannel.Name + "-复制");
            _channels.Add(newChannel);
            channelListBox.SelectedItem = _channels[_channels.Count - 1];
            AppManager.AddMemChannel(newChannel); // 内存通道对象
            SaveChannels();
            List<Device> devices = AppManager.DeviceDao.GetDevicesByChlId(oldId);
            if (devices != null)
            {
                List<Device> cloneDevices = new List<Device>();
                List<DataItem> cloneDataItems = new List<DataItem>();
                foreach (Device device in devices)
                {
                    string devId = IdHelper.GuidToString();
                    cloneDevices.Add(device.Clone(devId, newChannel.Id));
                    List<DataItem> dataItems = AppManager.DataItemDao.GetDataItemsByDevId(device.Id);
                    if (dataItems != null)
                    {
                        foreach (DataItem item in dataItems)
                        {
                            cloneDataItems.Add(item.Clone(IdHelper.GuidToString(), devId));
                        }
                    }
                }
                AppManager.DeviceDao.InsertEntities(cloneDevices);
                AppManager.DataItemDao.InsertEntities(cloneDataItems);
            }
        }
        private void MiDevCopy_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectDevice == null)
            {
                MessageBox.Show("请选择要复制的设备!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            string devId = IdHelper.GuidToString();
            Device device = selectDevice.Clone(devId, selectDevice.ChannelId);
            _devices.Add(device);
            deviceListBox.SelectedItem = _devices[_devices.Count - 1];
            SaveDevices();
        }
        private void MiChlDel_OnClick(object sender, RoutedEventArgs e)
        {
            BtnDelChannel_OnClick(null,null);
        }

        private void MiDevCopyAll_OnClick(object sender, RoutedEventArgs e)
        {
            if (selectDevice == null)
            {
                MessageBox.Show("请选择要复制的设备!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            string oldId = selectDevice.Id;
            string devId = IdHelper.GuidToString();
            Device device = selectDevice.Clone(devId, selectDevice.ChannelId);
            _devices.Add(device);
            deviceListBox.SelectedItem = _devices[_devices.Count - 1];
            SaveDevices();

            List<DataItem> dataItems = AppManager.DataItemDao.GetDataItemsByDevId(oldId);
            if (dataItems != null)
            {
                List<DataItem> cloneDataItems = new List<DataItem>();
                foreach (DataItem item in dataItems)
                {
                    cloneDataItems.Add(item.Clone(IdHelper.GuidToString(), devId));
                }
                AppManager.DataItemDao.InsertEntities(cloneDataItems);
            }
           
        }

        private void MiDevDel_OnClick(object sender, RoutedEventArgs e)
        {
            BtnDelDevice_OnClick(null,null);
        }
    }
}
